#include <main.h>

typedef void (*oberver_callback)(u8 *para);

#define RTC_SLAVE_ADDRESS  0x64    //写地址
#define RTC_SLAVE_RADDRESS 0x65    //读地址

#define RTC_IDEL        0
#define RTC_Cmd_W       1
#define RTC_Cmd_R       2

typedef struct
{
	u16 	DV_Addr;			/*器件地址*/
	u16 	REG_Addr;			/*写REG-H地址*/
	u16		P_Tx_DataArr[11];	/*发送的数据数组指针地址*/
	u8		Data_Lenth;			/*数据长度 发送长度为上方总长度*/
}ECU_RTC_TX_STR;

ECU_RTC_TX_STR  RTC_TxStr;


typedef struct
{
    u16     DV_Addr;			/*器件地址*/
    u16     REG_Addr;			/*写REG-H地址*/
    u16     DV_RAddr;			/*读器件地址*/
    u16     P_Tx_DataArr[11];	/*发送的数据数组指针地址*/
    u8      Data_Lenth;			/*数据长度 发送长度为上方总长度*/
    u16     P_Rx_DataArr[11];	/*接收的数据数组指针地址*/
}ECU_RTC_RX_STR;


ECU_RTC_RX_STR	RTC_RxStr;

u8 G_u8_RTC_REG_RAdd = 0;
u8 G_u8_RTC_REG_WAdd = 0;

u8 G_u8_RTC_Data_Lenth = 0;
u8 G_u8_RTC_DataCont = 0;

u32 G_u32_RTC_Data_WAdd = 0;
u32 G_u32_RTC_Data_RAdd = 0;
oberver_callback pfunc_wobserver;
oberver_callback pfunc_robserver;

/************************************************
*名称: bin2bcd()
*说明:
*功能:十六进制转换为BCD码
*调用:
*输入:
*输出:
*************************************************/

u8 bin2bcd(u8 val)
{
	return (((val / 10) << 4) + val % 10);
}


/************************************************
*名称: bcd2bin()
*说明:
*功能: BCD码转换为十六进制
*调用:
*输入:
*输出:
*************************************************/

u8 bcd2bin(u8 val)
{
	return ((val&0x0f)+10*(u8)(val >> 4));
}

/************读取数据************/
void ECU_RTC_RX_Tcomd(u8 u8_Lenth)
{
    u8 u8_i = 0;
    for(u8_i = 0;u8_i < u8_Lenth;u8_i++)
    {
        RTC_RxStr.P_Tx_DataArr[u8_i] = IIC_Reve(0x00);
    }
    RTC_RxStr.P_Tx_DataArr[u8_i] = IIC_Stop(0x00);
}

void ECU_RTC_READ_DATA(u16 REG_Add,u8 u8_Lenth)
{
    RTC_RxStr.DV_Addr = IIC_Start(RTC_SLAVE_ADDRESS);
    RTC_RxStr.REG_Addr = IIC_Send(REG_Add);
    RTC_RxStr.DV_RAddr = IIC_Start(RTC_SLAVE_RADDRESS);
    RTC_RxStr.Data_Lenth = u8_Lenth + 4;  /*包括START BIT check*/
    ECU_RTC_RX_Tcomd(u8_Lenth);
    ECU_IIC_DMA_RDATA((u32)(&(RTC_RxStr.DV_Addr)),(u32)(&(RTC_RxStr.P_Rx_DataArr)),RTC_RxStr.Data_Lenth);
}

void ECU_RTC_Deal_RData(u8* P_u8_Data,u8 u8_Lenth)
{
    u8 u8_Count = 0;
    for(u8_Count = 0;u8_Count < u8_Lenth;u8_Count++)
    {
        *(P_u8_Data + u8_Count) = (RTC_RxStr.P_Rx_DataArr[u8_Count+1] & 0xFF);
    }
}

/************写入数据************/
void ECU_RTC_Deal_WData(u8* P_u8_Data,u8 u8_Lenth)
{
    u8 u8_Count = 0;
    for(u8_Count = 0;u8_Count < u8_Lenth;u8_Count++)
    {
        RTC_TxStr.P_Tx_DataArr[u8_Count]=((*(P_u8_Data + u8_Count)) & 0xFF);
    }
    RTC_TxStr.P_Tx_DataArr[u8_Lenth]=IIC_Stop(0x00);
}

void ECU_RTC_WRIT_DATA(u16 REG_Add,u8 u8_Lenth)
{
    RTC_TxStr.DV_Addr = IIC_Start(RTC_SLAVE_ADDRESS);
    RTC_TxStr.REG_Addr = IIC_Send(REG_Add);
    RTC_TxStr.Data_Lenth = u8_Lenth + 3; /*包括START BIT check*/
    ECU_IIC_DMA_WDATA((u32)(&(RTC_TxStr.DV_Addr)),RTC_TxStr.Data_Lenth);
}



u8 ECU_RTC_Run_WData(void)
{
	u8 u8_Status = false;
	u8 u8_W_Lenth  = 0;
    
    if(G_u8_RTC_DataCont < G_u8_RTC_Data_Lenth)
    {
        /************判断存储的数据长度是否大于10************/
        if((G_u8_RTC_Data_Lenth - G_u8_RTC_DataCont) > 10)
        {
            u8_W_Lenth = 10;
        }
        else
        {
            u8_W_Lenth = G_u8_RTC_Data_Lenth - G_u8_RTC_DataCont;
        }
        ECU_RTC_Deal_WData((u8*)G_u32_RTC_Data_WAdd,u8_W_Lenth);
        ECU_RTC_WRIT_DATA(G_u8_RTC_REG_WAdd,u8_W_Lenth);
        G_u32_RTC_Data_WAdd = G_u32_RTC_Data_WAdd + u8_W_Lenth;
        G_u8_RTC_REG_WAdd = G_u8_RTC_REG_WAdd + u8_W_Lenth;
        G_u8_RTC_DataCont = G_u8_RTC_DataCont + u8_W_Lenth;
    }
    else
    {
        /*最后一帧数据，置位完成标志*/
        if(pfunc_wobserver)
            pfunc_wobserver((u8*)G_u32_RTC_Data_WAdd-u8_W_Lenth);
    
        u8_Status = true;
    }
	return u8_Status;
}



u8 ECU_RTC_Run_RData(void)
{
	u8 u8_Status = false;
	u8 u8_R_Lenth = 0;
	static u8 S_u8_R_Lenth  = 0;

	if(G_u8_RTC_DataCont < G_u8_RTC_Data_Lenth)
	{
		/************判断存储的数据长度是否大于10************/
		if((G_u8_RTC_Data_Lenth - G_u8_RTC_DataCont) > 10)
		{
			u8_R_Lenth = 10;
		}
		else
		{
			u8_R_Lenth = G_u8_RTC_Data_Lenth - G_u8_RTC_DataCont;
		}
		if(G_u8_RTC_DataCont != 0)
		{
			ECU_RTC_Deal_RData((u8*)G_u32_RTC_Data_RAdd - S_u8_R_Lenth,S_u8_R_Lenth);
		}
		S_u8_R_Lenth = u8_R_Lenth;
		ECU_RTC_READ_DATA(G_u8_RTC_REG_RAdd,u8_R_Lenth);
		G_u32_RTC_Data_RAdd = G_u32_RTC_Data_RAdd + u8_R_Lenth;
		G_u8_RTC_REG_RAdd = G_u8_RTC_REG_RAdd + u8_R_Lenth;
		G_u8_RTC_DataCont = G_u8_RTC_DataCont + u8_R_Lenth;
	}
	else
	{
		ECU_RTC_Deal_RData((u8*)G_u32_RTC_Data_RAdd-S_u8_R_Lenth,S_u8_R_Lenth);
        if(pfunc_robserver)
            pfunc_robserver((u8*)G_u32_RTC_Data_RAdd-S_u8_R_Lenth);
		/*最后一帧数据，置位完成标志*/
		u8_Status = true;
		S_u8_R_Lenth = 0;

	}
	return u8_Status;
}

u8 G_u8_RTC_RUN_CMD = 0;
u8 G_u8_RTC_RUN_CmdNum = 0;

void ECU_RTC_RUN(void)
{
	u8 u8_Status = 0;

    
	/*选择运行的指令码-对应的函数体*/
	switch(G_u8_RTC_RUN_CMD)
	{
		case RTC_IDEL:
		{
			break;
		}
		case RTC_Cmd_W:
		{
			u8_Status = ECU_RTC_Run_WData();
			if(u8_Status)
			{
				G_u8_RTC_RUN_CMD = RTC_IDEL;
			}
			break;
		}
		case RTC_Cmd_R:
		{
			u8_Status = ECU_RTC_Run_RData();
			if(u8_Status)
			{
				G_u8_RTC_RUN_CMD = RTC_IDEL;
			}
			break;
		}
		default:
		{
            G_u8_RTC_RUN_CMD = RTC_IDEL;
            break;
		}
	}
}

void ECU_RTC_WR_DATA(u8 Reg_Addr,u32 Data_Addr,u8 Data_Lenth,oberver_callback func)
{
    /*初始化传递参数*/
    G_u8_RTC_REG_WAdd = Reg_Addr;
    G_u32_RTC_Data_WAdd = Data_Addr;
    G_u8_RTC_Data_Lenth = Data_Lenth;
    G_u8_RTC_DataCont = 0;
    G_u8_RTC_RUN_CMD=RTC_Cmd_W;
    pfunc_wobserver=func;
}

void ECU_RTC_RR_DATA(u32 Data_Addr,u8 Reg_Addr,u8 Data_Lenth,oberver_callback func)
{
    /*初始化传递参数*/
    G_u8_RTC_REG_RAdd = Reg_Addr;
    G_u32_RTC_Data_RAdd = Data_Addr;
    G_u8_RTC_Data_Lenth = Data_Lenth;
    G_u8_RTC_DataCont = 0;
    G_u8_RTC_RUN_CMD=RTC_Cmd_R;
    pfunc_robserver=func;
}

u8 G_u8_RTC_WDataArr[155] = {0};
u8 G_u8_RTC_RDataArr[155] = {0};
bool bReadNotify=false;
bool bWriteNotify=false;

void rtc_read_callback(u8 *para)
{
    bReadNotify=true;
}

void rtc_write_callback(u8 *para)
{
    bWriteNotify=true;
}

ST_TIME G_rtc_time;

void rtc_time_read_callback(u8 *para)
{
    u8 *ptr=(u8 *)para;
    
    G_rtc_time.Sencond=*(u8 *)para;
    bReadNotify=true;
    G_rtc_time.Sencond=bcd2bin(ptr[0]);
    G_rtc_time.Min=bcd2bin(ptr[1]);
    G_rtc_time.Hour=bcd2bin(ptr[2]);
    G_rtc_time.Week=bcd2bin(ptr[3]);
    G_rtc_time.Day=bcd2bin(ptr[4]);
    G_rtc_time.Month=bcd2bin(ptr[5]);
    G_rtc_time.Year=bcd2bin(ptr[6])+2000;
}

void ECU_RX8010_Buffer_Read(u8 *pbuffer,u8 add,u8 num,oberver_callback func)
{
    ECU_RTC_RR_DATA((u32)pbuffer,add,num,func);
}

void ECU_RX8010_Buffer_Write(u8 add,u8 *pbuffer,u8 num,oberver_callback func)
{
    ECU_RTC_WR_DATA(add,(u32)pbuffer,num,func);
}

u8 step=0;
u8 action=0;

void ECU_RTC_Test(void)
{
    /*read ram to check the RTC whether alive*/
    if(step==0){
        if(!action){
            bWriteNotify=false;
            G_u8_RTC_WDataArr[0]=0xA6;
            ECU_RX8010_Buffer_Write(RX8010_REG_RAM,G_u8_RTC_WDataArr,1,rtc_write_callback);
            action=1;
        }
        if(bWriteNotify){
            action=0;
            step=1;
            return;
        }
    }
    else if(step==1){
        if(!action){
            bReadNotify=false;
            ECU_RX8010_Buffer_Read(G_u8_RTC_RDataArr,RX8010_REG_RAM,1,rtc_read_callback);
            action=1;
        }
        if(bReadNotify){
            action=0;
            step=2;
            return;
        }
    }
    else if(step==2){
        
        if(!action){
            G_u8_RTC_WDataArr[0] = bin2bcd(50);
            G_u8_RTC_WDataArr[1] = bin2bcd(10);
            G_u8_RTC_WDataArr[2] = bin2bcd(11);
            G_u8_RTC_WDataArr[3] = bin2bcd(4);
            G_u8_RTC_WDataArr[4] = bin2bcd(9);
            G_u8_RTC_WDataArr[5] = bin2bcd(5);
            G_u8_RTC_WDataArr[6] = bin2bcd(24);

            bWriteNotify=false;
            ECU_RX8010_Buffer_Write(RX8010_REG_SEC, G_u8_RTC_WDataArr, 7,rtc_write_callback);
            action=1;
        }
        if(bWriteNotify){
            action=0;
            step=3;
            return;
        }
    }
    else if(step==3){
        if(!action){
            bReadNotify=false;
            ECU_RX8010_Buffer_Read(G_u8_RTC_RDataArr, RX8010_REG_SEC, 7,rtc_time_read_callback);
            action=1;
        }
        if(bReadNotify){
            action=0;
            step=3;
            return;
        }
    }
}

